package swf 
{
	import flash.events.EventDispatcher;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.media.Sound;
	import flash.net.URLRequest;
	/**
	 * ...
	 * @author FireKnight
	 */
	public class SWFLibrary extends EventDispatcher 
	{
		private var _libraryURL			: String;
		private var _loaded				: Boolean;
		private var _request			: URLRequest;
		private var _loader				: Loader;
		private var _loaderInfo			: LoaderInfo;
		public function SWFLibrary() 
		{
			_request = new URLRequest();
			_loader = new Loader();
			_loader.contentLoaderInfo.addEventListener( Event.COMPLETE, handleLoadComplete )
			
			_loaded = false;
		}
		
		// === A P I ===
		/**
		 * load a SWF into this 
		 * 
		 * @param		assetURL		the URL of a SWF file to load
		 * @return						nothing
		 */ 
		public function load( assetURL:String ): void
		{
			_loaded = false;
			_request.url = assetURL;
			_loader.load( _request );
			
			_libraryURL = assetURL;
		}
		
		/**
		 * get whether this is loaded or not
		 * 
		 * @param						none
		 * @return						nothing
		 */
		public function get loaded(): Boolean
		{
			return _loaded;
		}
		
		/**
		 * retrieves an instance of the specified Sprite
		 * 
		 * @param		className		name of the class that extends Sprite
		 * @return						an instance of that class, or null if not found
		 */ 
		public function getSprite( className:String ): Sprite
		{
			var Asset:Class = getAsset( className );
			
			if ( Asset ) return Sprite( new Asset() );
			return null;
		}
		
		/**
		 * retrieves an instance of the specified MovieClip
		 * 
		 * @param		className		name of the class that extends Sprite
		 * @return						an instance of that class, or null if not found
		 */
		 public function getMovieClip( className:String ): MovieClip
		 {
		 	var Asset:Class = getAsset( className );
		 	
		 	if ( Asset ) return MovieClip( new Asset() );
		 	return null;
		 }
		
		/**
		 * retrieves an instance of the specified Sound
		 * 
		 * @param		className		name of the class that extends Sound
		 * @return						an instance of that sound, or null if not found
		 */
		public function getSound( className:String ): Sound
		{
			var Asset:Class = getAsset( className );
			
			if ( Asset ) return Sound( new Asset() );
			return null;
		}
		
		// === P R I V A T E   M E T H O D S ===
		/**
		 * finds the requested class in the SWF and returns it uninstantiated as a Class object
		 *
		 * @param		className		the name of the requested class
		 * @return						the requested class as a Class object
		 */
		public function getAsset( className:String ): Class
		{
			try
			{
				var Asset:Class = _loaderInfo.applicationDomain.getDefinition( className ) as Class;
			} 
			catch ( error:ReferenceError )
			{
				trace( "Asset '" + className + "' not found in '" + _libraryURL + "'" );
				return null;
			}
			return Asset;
		}
		
		// === E V E N T   H A N D L E R S ===
		/**
		 * called when the SWF has been successfully loaded
		 * dispatches AssetEvent.LOADED when called
		 * 
		 * @param		event			an Event object from _loader.contentLoaderInfo
		 * @return						nothing
		 */
		private function handleLoadComplete( event:Event ): void
		{
			_loaded = true;
			_loaderInfo = _loader.contentLoaderInfo;
			dispatchEvent( new Event( Event.COMPLETE ) );
		}
		
	}

}